package com.moli.iov.his.hbaseService.impl;

import com.alibaba.fastjson.JSON;
import com.moli.iov.common.hbase.dto.query.GetResultScannerQueDto;
import com.moli.iov.common.hbase.service.IHbaseService;
import com.moli.iov.his.dto.RealTimeInfoHbaseDto;
import com.moli.iov.his.hbaseService.IOrgDataCountService;
import com.moli.iov.his.util.HisUtil;
import com.moli.iov.util.DateUtil;
import com.moli.iov.vehicle.model.po.VehicleTbox;
import lombok.extern.slf4j.Slf4j;
import org.apache.hadoop.hbase.filter.CompareFilter;
import org.apache.hadoop.hbase.filter.Filter;
import org.apache.hadoop.hbase.filter.RegexStringComparator;
import org.apache.hadoop.hbase.filter.RowFilter;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.util.*;


/**
 * 原始报文统计查询实现类
 */
@Slf4j
@Service(value = "iOrgDataCountService")
public class OrgDataCountServiceImpl implements IOrgDataCountService {
    @Resource
    private IHbaseService iHbaseService;

    @Override
    public List<String> queryDistinctVinByYesterDayLogin() {
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT+08:00"));
        //calendar.add(Calendar.DATE,-1);
        Date time = calendar.getTime();
        time.setHours(0);
        time.setMinutes(0);
        time.setSeconds(0);
        String endStr = String.valueOf(Long.MAX_VALUE - time.getTime());
        //1900800000L为24小时相差的毫秒数
        String startStr = String.valueOf(Long.MAX_VALUE - (time.getTime() + 1900800000L));
        String exprStart = "^[a-zA-Z0-9]{17}" + "_" + startStr;
        String exprEnd = "^[a-zA-Z0-9]{17}" + "_" + endStr;
        Filter filterStart = new RowFilter(CompareFilter.CompareOp.GREATER, new RegexStringComparator(exprStart));
        Filter filterEnd = new RowFilter(CompareFilter.CompareOp.LESS_OR_EQUAL, new RegexStringComparator(exprEnd));
        ArrayList<Filter> filters = new ArrayList<>(0);
        filters.add(filterStart);
        filters.add(filterEnd);
        log.info("queryStartTime:" + System.currentTimeMillis());
        HashMap<String, byte[]> reMap = null;

        try {
            GetResultScannerQueDto getResultScannerQueDto = new GetResultScannerQueDto();
            getResultScannerQueDto.setTableName("moli:org_iov_login");
            getResultScannerQueDto.setFilters(filters);
            getResultScannerQueDto.setFamily("fm1");
            getResultScannerQueDto.setColumn("messageContent");
            reMap = iHbaseService.getResultScanner(getResultScannerQueDto);
        } catch (Exception e) {
            log.error("hbase:moli:org_iov_login查询异常..........{}", e);
        }
        log.info("queryEndTime:" + System.currentTimeMillis());
        List<String> list = new ArrayList<>();

        for (String key : reMap.keySet()) {
            if (key.length() > 31) {
                String vin = key.substring(0, 17);
                if (!list.contains(vin)) {
                    list.add(vin);
                }
            }
        }
        //return new ArrayList<>(new HashSet(list));
        return list;
    }

    @Override
    public List<String> queryDistinctVinByLogin(List<VehicleTbox> vehicleTboxes) {

        List<String> vinList = new ArrayList<>(0);
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT+08:00"));

        Date time = calendar.getTime();
        time.setHours(0);
        time.setMinutes(0);
        time.setSeconds(0);
        //大 10
        long end = time.getTime();
        // 小 8
        long start = time.getTime() - (86400000L);
        //10
        String startStr = String.valueOf(Long.MAX_VALUE - end);
        //12
        String endStr = String.valueOf(Long.MAX_VALUE - start);
        int sum = 0;
        if (vehicleTboxes != null && vehicleTboxes.size() > 0) {
            for (VehicleTbox vehicleTbox : vehicleTboxes) {
                if (vehicleTbox == null) {
                    continue;
                }
                String vin = vehicleTbox.getVin();
                String startRow = vin + "_" + startStr;
                String stopRow = vin + "_" + endStr;
                HashMap<String, byte[]> results = null;
                try {
                    GetResultScannerQueDto getResultScannerQueDto = new GetResultScannerQueDto();
                    getResultScannerQueDto.setTableName("moli:org_iov_login");
                    getResultScannerQueDto.setStartRow(startRow);
                    getResultScannerQueDto.setStopRow(stopRow);
                    getResultScannerQueDto.setFamily("fm1");
                    getResultScannerQueDto.setColumn("messageContent");
                    log.info("{}表查询条件startRow------{},stopRow------{}", "moli:org_iov_login", startRow, stopRow);
                    results = iHbaseService.getResultScanner(getResultScannerQueDto);
                } catch (Exception e) {
                    log.error("hbase:moli:org_iov_login查询异常..........{}", e);
                }
                for (String key : results.keySet()) {
                    log.info("****车辆{}上线****:{}", vin, key);
                    if (!vinList.contains(vin)) {
                        vinList.add(vin);
                    }
                }
                sum += 1;
            }
            log.info("统计车辆vin总数:----------------->" + sum);
        }
        log.info("vinList总数：" + vinList.size());
        log.info("统计结果listvin:------------------------>" + JSON.toJSONString(vinList));
        return vinList;
    }

    @Override
    public List<RealTimeInfoHbaseDto> queryRealTimeBusinessByTimeAndVin(Date beginTime, Date endTime, String vin) {
        List<RealTimeInfoHbaseDto> dtos = new ArrayList<>(0);
        log.info("车辆轨迹查询beginTime:------------>{}", beginTime.getTime());
        log.info("车辆轨迹查询endTime:-------------->{}", endTime.getTime());
        String startRow = vin + "_" + (Long.MAX_VALUE - endTime.getTime());
        String stopRow = vin + "_" + (Long.MAX_VALUE - beginTime.getTime());
        log.info("车辆轨迹查询startRow：" + startRow);
        log.info("车辆轨迹查询stopRow:" + stopRow);
        log.info("--------------查询开始:" + System.currentTimeMillis());
        String htable = "moli:business_vehicle_realTime";
        try {
            Date limitDate = DateUtil.parser(DateUtil.YEAR_SECOND, "2019-04-08 00:00:00");
            if (endTime.compareTo(limitDate) <= 0) {
                htable = "moli:business_vehicle_realTime_3";
            }

        } catch (ParseException e) {
            log.error("日期解析异常", e);
        }
        HashMap<String, byte[]> results = null;
        try {
            GetResultScannerQueDto getResultScannerQueDto = new GetResultScannerQueDto();
            getResultScannerQueDto.setColumn("messageContent");
            getResultScannerQueDto.setFamily("fm1");
            getResultScannerQueDto.setTableName(htable);
            getResultScannerQueDto.setStopRow(stopRow);
            getResultScannerQueDto.setStartRow(startRow);
            results = iHbaseService.getResultScanner(getResultScannerQueDto);
        } catch (Exception e) {
            log.error(htable + "查询异常-------{}", e);
        }

        if (results == null) {
            log.info("--------------未查询到任何数据:" + System.currentTimeMillis());
            return dtos;
        }
        log.info("--------------表{}查询结束", htable);
        String vin_result = null;
        RealTimeInfoHbaseDto realTimeInfoHbaseDto = null;
        for (String key : results.keySet()) {
            //获取行键中的vin
            vin_result = key.substring(0, 17);
            if (vin.equals(vin_result)) {
                realTimeInfoHbaseDto = HisUtil.ResultConvertToDto(key, results.get(key));
                if (null != realTimeInfoHbaseDto.getReportDate()) {
                    dtos.add(realTimeInfoHbaseDto);
                }
            }
        }
        //按照上报时间排序
        Collections.sort(dtos, new Comparator<RealTimeInfoHbaseDto>() {
            @Override
            public int compare(RealTimeInfoHbaseDto o1, RealTimeInfoHbaseDto o2) {
                return o1.getReportDate().compareTo(o2.getReportDate());
            }
        });
        log.info("查询结果遍历结束,遍历结果共{}条数据...............", dtos.size());
        return dtos;

    }

    /**
     * 单车分析请求接口
     *
     * @param beginTime
     * @param endTime
     * @param vin
     * @return
     */
    @Override
    public List<RealTimeInfoHbaseDto> queryRealTimeDataByTimeAndVin(Date beginTime, Date endTime, String vin) {

        long startWTime = System.currentTimeMillis();

        List<RealTimeInfoHbaseDto> dtos = new ArrayList<>(0);
        log.info("车辆轨迹查询beginTime:------------>{}", beginTime.getTime());
        log.info("车辆轨迹查询endTime:-------------->{}", endTime.getTime());
        String startRow = vin + "_" + (Long.MAX_VALUE - endTime.getTime());
        String stopRow = vin + "_" + (Long.MAX_VALUE - beginTime.getTime());
        log.info("车辆轨迹查询startRow：" + startRow);
        log.info("车辆轨迹查询stopRow:" + stopRow);
        log.info("--------------查询开始:" + System.currentTimeMillis());
        String htable = "moli:business_vehicle_realTime";
        try {
            Date limitDate = DateUtil.parser(DateUtil.YEAR_SECOND, "2019-04-08 00:00:00");
            if (endTime.compareTo(limitDate) <= 0) {
                htable = "moli:business_vehicle_realTime_3";
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        HashMap<String, byte[]> results = null;
        try {
            GetResultScannerQueDto getResultScannerQueDto = new GetResultScannerQueDto();
            getResultScannerQueDto.setColumn("messageContent");
            getResultScannerQueDto.setFamily("fm1");
            getResultScannerQueDto.setTableName(htable);
            getResultScannerQueDto.setStopRow(stopRow);
            getResultScannerQueDto.setStartRow(startRow);
            results = iHbaseService.getResultScanner(getResultScannerQueDto);
        } catch (Exception e) {
            log.error(htable + "查询异常-------{}", e);
        }

        if (results == null) {
            log.info("--------------未查询到任何数据:" + System.currentTimeMillis());
            return dtos;
        }
        long endWTime = System.currentTimeMillis();
        log.info("查询hbase执行时长:{}", (endWTime - startWTime));
//        log.info("--------------查询结束:" + System.currentTimeMillis()+"htable:"+htable);
        for (String key : results.keySet()) {
            //获取行键中的vin
            String vin_result = key.substring(0, 17);
            if (vin.equals(vin_result)) {
                RealTimeInfoHbaseDto realTimeInfoHbaseDto = HisUtil.ResultConvertToDto(key, results.get(key));
                if (null != realTimeInfoHbaseDto.getReportDate()) {
                    dtos.add(realTimeInfoHbaseDto);
                }
            }
        }

        long endW1Time = System.currentTimeMillis();
        log.info("反序列化执行时长:{}", (endW1Time - endWTime));
        //按照上报时间排序
        Collections.sort(dtos, new Comparator<RealTimeInfoHbaseDto>() {
            @Override
            public int compare(RealTimeInfoHbaseDto o1, RealTimeInfoHbaseDto o2) {
                return o1.getReportDate().compareTo(o2.getReportDate());
            }
        });
        long endW2Time = System.currentTimeMillis();
        log.info("排序执行时长:{}", (endW2Time - endW1Time));
        return dtos;

    }

}
